﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;
using System.IO;

namespace Tetris
{
    class Gl
    {
    }

    enum FiguteType { Line, G1, G2, Z1, Z2, Cub, T };

    class Figure
    {
        public int Sz;
        public bool[,] Cl;
        public Point Pos;
        public FiguteType Tp;
        bool isRotated = false; // признак поворота для фигур, которые не должны вертеться полный круг

        public Figure(FiguteType Tp, Point Pos)
        {
            this.Tp = Tp;
            this.Pos = Pos;
            switch (Tp)
            {
                case FiguteType.Line:
                    {
                        CreateCl(4);
                        Cl[1, 0] = true;
                        Cl[1, 1] = true;
                        Cl[1, 2] = true;
                        Cl[1, 3] = true;
                        break;
                    }
                case FiguteType.G1:
                    {
                        CreateCl(3);
                        Cl[0, 0] = true;
                        Cl[0, 1] = true;
                        Cl[1, 1] = true;
                        Cl[2, 1] = true;
                        break;
                    }
                case FiguteType.G2:
                    {
                        CreateCl(3);
                        Cl[2, 0] = true;
                        Cl[0, 1] = true;
                        Cl[1, 1] = true;
                        Cl[2, 1] = true;
                        break;
                    }
                case FiguteType.Z1:
                    {
                        CreateCl(3);
                        Cl[0, 0] = true;
                        Cl[1, 0] = true;
                        Cl[1, 1] = true;
                        Cl[2, 1] = true;
                        break;
                    }
                case FiguteType.Z2:
                    {
                        CreateCl(3);
                        Cl[2, 0] = true;
                        Cl[1, 0] = true;
                        Cl[1, 1] = true;
                        Cl[0, 1] = true;
                        break;
                    }
                case FiguteType.Cub:
                    {
                        CreateCl(2);
                        Cl[0, 0] = true;
                        Cl[0, 1] = true;
                        Cl[1, 0] = true;
                        Cl[1, 1] = true;
                        break;
                    }
                case FiguteType.T:
                    {
                        CreateCl(3);
                        Cl[1, 0] = true;
                        Cl[0, 1] = true;
                        Cl[1, 1] = true;
                        Cl[2, 1] = true;
                        break;
                    }
            }
        }

        public Figure(BinaryReader br)
        {
            br.ReadInt32(); // версия
            Sz = br.ReadByte(); // размер
            Pos = new Point(br.ReadByte(), br.ReadByte()); // позиция
            Tp = (FiguteType)br.ReadByte(); // тип
            isRotated = br.ReadBoolean(); // признак поворота
            // матрица
            Cl = new bool[Sz, Sz];
            for (int i = 0; i < Sz; i++)
                for (int j = 0; j < Sz; j++)
                    Cl[i, j] = br.ReadBoolean();
        }

        public void Save(BinaryWriter bw)
        {
            bw.Write(0); // версия
            bw.Write((byte)Sz);// размер
            bw.Write((byte)Pos.X); bw.Write((byte)Pos.Y); // позиция
            bw.Write((byte)Tp); // тип
            bw.Write(isRotated); // признак поворота
            // матрица
            for (int i = 0; i < Sz; i++)
                for (int j = 0; j < Sz; j++)
                    bw.Write(Cl[i, j]);
        }

        void CreateCl(int sz)
        {
            Sz = sz;
            Cl = new bool[sz, sz];
            for (int i = 0; i < sz; i++)
                for (int j = 0; j < sz; j++)
                    Cl[i, j] = false;
        }

        public void Rotate(bool[,] FieldCl, Size FieldSize)
        {
            if (Tp == FiguteType.Cub) return;

            Point newPos = Pos;
            bool[,] newCl = new bool[Sz, Sz];
            int minX = int.MaxValue;
            int maxX = int.MinValue;
            int maxY = int.MinValue;
            for (int i = 0; i < Sz; i++)
                for (int j = 0; j < Sz; j++)
                {
                    if (isRotated) newCl[i, j] = Cl[j, Sz - 1 - i];
                    else newCl[i, j] = Cl[Sz - 1 - j, i];
                    if (newCl[i, j])
                    {
                        int x = i + Pos.X;
                        int y = j + Pos.Y;
                        if (minX > x) minX = x;
                        if (maxX < x) maxX = x;
                        if (maxY < y) maxY = y;
                    }
                }

            // смещение позиции, если фигура не умещается по оси X
            if (minX < 0) newPos.X -= minX;
            if (maxX >= FieldSize.Width) newPos.X -= maxX - FieldSize.Width + 1;

            // если повернутая фигура не умещается по оси Y не поворачивать
            if (maxY >= FieldSize.Height) return;

            // проверка на пересечение повернутой фигуры с блокими поля
            // если повернутая фигура пересекается, не поворачивать фигуру
            for (int i = 0; i < Sz; i++)
                for (int j = 0; j < Sz; j++)
                    if (FieldCl[i + Pos.X, j + Pos.Y])
                        return;

            Pos = newPos;
            Cl = newCl;
            if (Tp == FiguteType.Line || Tp == FiguteType.Z1 || Tp == FiguteType.Z2)
                isRotated = !isRotated;
        }
    }
}
